home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
xlib
/
tcilight.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
14KB
|
543 lines
/*
* (c) Copyright 1994, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*
** Test Color Index Lighting
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <GL/glx.h>
float indexScale = 1.0;
int useLighting = 0;
int useTwoSide = 0;
int useLocalLight = 0;
int useLocalViewer = 0;
int useSpot = 0;
int useAtten = 0;
int whichObject = 0;
float modelAmb[4] = { 0.0, 0.0, 0.0, 0.0 };
float lightPosInf[4] = { 0.0, 0.0, 1.0, 0.0 };
float lightPosLoc[4] = { 0.0, 0.0, 4.0, 1.0 };
float lightAmb[4] = { 0.2, 0.2, 0.2, 0.0 };
float lightDiff[4] = { 0.6, 0.6, 0.6, 0.0 };
float lightSpec[4] = { 0.2, 0.2, 0.2, 0.0 };
float lightSpotDir[3] = { 0.0, 0.0, -1.0 };
float lightSpot[2] = { 100.0, 30.0 };
float lightAtten[3] = { 0.80, 0.25, 0.05 };
float matIndexRange[3] = { 0.05, 0.75, 0.95 };
float matIndexes[3] = { 0.0, 0.0, 0.0 };
float matShininess[1] = { 10.0 };
static void
init(void)
{
glClearIndex(0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -2.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glLineWidth(2.0);
}
static void
reconfig(void)
{
glLightModelfv(GL_AMBIENT, modelAmb);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, useLocalViewer);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, useTwoSide);
glLightfv(GL_LIGHT0, GL_POSITION, useLocalLight ? lightPosLoc:lightPosInf);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightSpotDir);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, useSpot ? lightSpot[0]:1.0);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, useSpot ? lightSpot[1]:180.0);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, useAtten ? lightAtten[0]:1.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, useAtten ? lightAtten[1]:0.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, useAtten ? lightAtten[2]:0.0);
glEnable(GL_LIGHT0);
matIndexes[0] = matIndexRange[0]*indexScale;
matIndexes[1] = matIndexRange[1]*indexScale;
matIndexes[2] = matIndexRange[2]*indexScale;
glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, matIndexes);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, matShininess);
if (useLighting) {
glEnable(GL_LIGHTING);
} else {
glDisable(GL_LIGHTING);
}
}
static void
drawMaterialMeter(void)
{
if (useLighting) glDisable(GL_LIGHTING);
glPushMatrix();
glLoadIdentity();
glTranslatef(0.7, -0.9, -1.0);
glScalef(0.2, 1.8, 1.0);
glBegin(GL_LINES);
glIndexf(0.95*indexScale);
glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0);
glVertex2f(1.0, 0.0); glVertex2f(1.0, 1.0);
glVertex2f(1.0, 1.0); glVertex2f(0.0, 1.0);
glVertex2f(0.0, 1.0); glVertex2f(0.0, 0.0);
glIndexf(0.25*indexScale);
glVertex2f(0.0, matIndexRange[0]); glVertex2f(1.0, matIndexRange[0]);
glIndexf(0.50*indexScale);
glVertex2f(0.0, matIndexRange[1]); glVertex2f(1.0, matIndexRange[1]);
glIndexf(0.75*indexScale);
glVertex2f(0.0, matIndexRange[2]); glVertex2f(1.0, matIndexRange[2]);
glEnd();
glPopMatrix();
if (useLighting) glEnable(GL_LIGHTING);
}
static void
drawGrid(void)
{
static int dlist = 0;
if (dlist) {
glCallList(dlist);
} else {
int u = 8, v = 8;
float du = 1.0 / u;
float dv = 1.0 / v;
int i, j;
dlist = glGenLists(1);
glNewList(dlist, GL_COMPILE_AND_EXECUTE);
glNormal3f(0.0, 0.0, 1.0);
glBegin(GL_QUADS);
for (j=0; j<v; ++j) {
float y = j * dv;
for (i=0; i<u; ++i) {
float x = i * du;
if ((i ^ j) & 1) {
glIndexf(0.25*indexScale);
} else {
glIndexf(0.75*indexScale);
}
glVertex2f(x , y );
glVertex2f(x+du, y );
glVertex2f(x+du, y+dv);
glVertex2f(x , y+dv);
}
}
glEnd();
glEndList();
}
}
static void
drawCylinder(void)
{
static int dlist = 0;
if (dlist) {
glCallList(dlist);
} else {
int u = 16;
float du = (2*M_PI) / u;
int i, j;
dlist = glGenLists(1);
glNewList(dlist, GL_COMPILE_AND_EXECUTE);
glBegin(GL_TRIANGLE_STRIP);
for (i=0; i<=u; ++i) {
float t = i * du;
float x = 0.5 * (float)cos((double) t) + 0.5;
float y = 0.5 * (float)sin((double) t) + 0.5;
glNormal3f(2.0 * (x - 0.5), 2.0 * (y - 0.5), 0.0);
glIndexf(0.80*indexScale);
glVertex3f(x, y, 0.5);
glIndexf(0.20*indexScale);
glVertex3f(x, y, -0.5);
}
glEnd();
glEndList();
}
}
#define NUM_OBJECTS 2
static void (*drawObject[NUM_OBJECTS])(void) = { drawGrid, drawCylinder };
static void
redraw(float xrot, float yrot)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawMaterialMeter();
glPushMatrix();
glRotatef(xrot, 1, 0, 0);
glRotatef(yrot, 0, 1, 0);
glPushMatrix();
glScalef(1.5, 1.5, 1.25);
glTranslatef(-0.5, -0.5, 0.0);
(*drawObject[whichObject])();
glPopMatrix();
glPopMatrix();
}
static Colormap
buildGrayScaleColormap(Display *dpy, XVisualInfo *vis)
{
Colormap cmap;
cmap = XCreateColormap(dpy, RootWindow(dpy, vis->screen),
vis->visual, AllocNone);
if (vis->class == PseudoColor) {
int mapSize = 1 << vis->depth;
int firstEntry = 0;
int entry;
unsigned long *pix;
pix = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pix, mapSize)) {
if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pix, mapSize-1)) {
fprintf(stderr, "can't alloc enough colormap entries\n");
exit(EXIT_FAILURE);
}
firstEntry = 1;
}
for (entry=firstEntry; entry<mapSize; ++entry) {
XColor col;
int val = entry * (0xffff / (mapSize-1));
col.pixel = entry;
col.red = val;
col.green = val;
col.blue = val;
col.flags = DoRed | DoGreen | DoBlue;
XStoreColor(dpy, cmap, &col);
}
free((void *) pix);
} else {
fprintf(stderr, "can't build colormap for selected visual\n");
exit(EXIT_FAILURE);
}
return cmap;
}
static Bool
waitForMapNotify(Display *dpy, XEvent *ev, XPointer arg)
{
return ((ev->type == MapNotify) && (ev->xmapping.window == (Window) arg));
}
static int visualAttrs[] = {
GLX_DOUBLEBUFFER,
GLX_BUFFER_SIZE, 4,
GLX_DEPTH_SIZE, 1,
GLX_LEVEL, 0,
None,
};
int
main(int argc, char **argv)
{
Display *dpy;
int scrn;
Window root;
XVisualInfo *vis;
GLXContext ctx;
Colormap cmap;
XSizeHints sizehints;
XSetWindowAttributes swa;
Window win;
XEvent ev;
char *name = "ColorIndex Lighting";
char *geometry = NULL;
int x = 0;
int y = 0;
unsigned int width = 300;
unsigned int height = 300;
int needsReconfig = 1;
int needsRedraw = 1;
int done = 0;
float xrot = 0.0;
float yrot = 0.0;
int x0, y0;
int i;
for (i=1; i<argc; ++i) {
if ((strcmp("-geometry", argv[i]) == 0) && (i+1 < argc)) {
geometry = argv[++i];
}
}
if ((dpy = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "can't open display\n");
exit(EXIT_FAILURE);
}
scrn = DefaultScreen(dpy);
root = RootWindow(dpy, scrn);
if ((vis = glXChooseVisual(dpy, scrn, visualAttrs)) == NULL) {
fprintf(stderr, "can't find visual\n");
exit(EXIT_FAILURE);
}
if ((ctx = glXCreateContext(dpy, vis, NULL, True)) == NULL) {
fprintf(stderr, "can't create context\n");
exit(EXIT_FAILURE);
}
sizehints.flags = PPosition | PSize;
sizehints.width = (int) width;
sizehints.height = (int) height;
sizehints.x = x;
sizehints.y = y;
if (geometry) {
int flags = XParseGeometry(geometry, &x, &y, &width, &height);
if (flags & WidthValue) {
sizehints.flags |= USSize;
sizehints.width = (int) width;
}
if (flags & WidthValue) {
sizehints.flags |= USSize;
sizehints.height = (int) height;
}
if (flags & XValue) {
if (flags & XNegative) {
x = DisplayWidth(dpy, scrn) + x - sizehints.width;
}
sizehints.flags |= USPosition;
sizehints.x = x;
}
if (flags & YValue) {
if (flags & YNegative) {
y = DisplayHeight(dpy, scrn) + y - sizehints.height;
}
sizehints.flags |= USPosition;
sizehints.y = y;
}
}
cmap = buildGrayScaleColormap(dpy, vis);
swa.colormap = cmap;
swa.background_pixel = None;
swa.border_pixel = None;
win = XCreateWindow(dpy, root,
sizehints.x, sizehints.y,
sizehints.width, sizehints.height, 0,
vis->depth, InputOutput, vis->visual,
CWColormap | CWBackPixel | CWBorderPixel, &swa);
XSetStandardProperties(dpy, win, name, name, None, argv, argc, &sizehints);
XSelectInput(dpy, win,
StructureNotifyMask | ExposureMask |
KeyPressMask | ButtonPressMask | ButtonMotionMask);
XMapWindow(dpy, win);
XIfEvent(dpy, &ev, waitForMapNotify, (XPointer) win);
glXMakeCurrent(dpy, win, ctx);
indexScale = (1 << vis->depth) - 1;
init();
while (!done) {
do {
XNextEvent(dpy, &ev);
switch (ev.type) {
case KeyPress:
{
KeySym ks;
float p;
XLookupString(&ev.xkey, NULL, 0, &ks, NULL);
switch (ks) {
case XK_Escape:
done = 1;
break;
case XK_O: case XK_o:
whichObject = (whichObject + 1) % NUM_OBJECTS;
break;
case XK_L: case XK_l:
useLighting = !useLighting;
break;
case XK_T: case XK_t:
useTwoSide = !useTwoSide;
break;
case XK_K: case XK_k:
useLocalLight = !useLocalLight;
break;
case XK_V: case XK_v:
useLocalViewer = !useLocalViewer;
break;
case XK_P: case XK_p:
useSpot = !useSpot;
break;
case XK_N: case XK_n:
useAtten = !useAtten;
break;
case XK_A:
p = matIndexRange[0] + 0.005;
if (p < 0.0) p = 0.0;
if (p > 1.0) p = 1.0;
matIndexRange[0] = p;
break;
case XK_a:
p = matIndexRange[0] - 0.005;
if (p < 0.0) p = 0.0;
if (p > 1.0) p = 1.0;
matIndexRange[0] = p;
break;
case XK_D:
p = matIndexRange[1] + 0.005;
if (p < 0.0) p = 0.0;
if (p > 1.0) p = 1.0;
matIndexRange[1] = p;
break;
case XK_d:
p = matIndexRange[1] - 0.005;
if (p < 0.0) p = 0.0;
if (p > 1.0) p = 1.0;
matIndexRange[1] = p;
break;
case XK_S:
p = matIndexRange[2] + 0.005;
if (p < 0.0) p = 0.0;
if (p > 1.0) p = 1.0;
matIndexRange[2] = p;
break;
case XK_s:
p = matIndexRange[2] - 0.005;
if (p < 0.0) p = 0.0;
if (p > 1.0) p = 1.0;
matIndexRange[2] = p;
break;
default:
break;
}
}
needsReconfig = 1;
needsRedraw = 1;
break;
case ButtonPress:
x0 = ev.xbutton.x;
y0 = ev.xbutton.y;
break;
case MotionNotify:
yrot += (float)(ev.xmotion.x-x0) * (360.0 / (float) width);
if (yrot > 360) yrot = yrot - 360;
if (yrot < 0) yrot = 360 - yrot;
xrot += (float)(ev.xmotion.y-y0) * (360.0 / (float) height);
if (xrot > 360) xrot = xrot - 360;
if (xrot < 0) xrot = 360 - xrot;
x0 = ev.xmotion.x; y0 = ev.xmotion.y;
needsRedraw = 1;
break;
case ConfigureNotify:
width = (unsigned int) ev.xconfigure.width;
height = (unsigned int) ev.xconfigure.height;
needsReconfig = 1;
needsRedraw = 1;
break;
case Expose:
default:
needsRedraw = 1;
break;
}
} while (XPending(dpy));
if (needsReconfig) {
glViewport(0, 0, (float) width, (float) height);
reconfig();
needsReconfig = 0;
}
if (needsRedraw) {
redraw(xrot, yrot);
glXSwapBuffers(dpy, win);
needsRedraw = 0;
}
}
}